/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package musicbox;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.util.Observable;
import java.util.Observer;

import javax.sound.midi.Instrument;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.Receiver;
import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;

import neuralmusic.brain.RTScheduler;
import neuralmusic.brain.module.Scheduler;

import uk.co.drpj.AudioAndMidiSystem;
import uk.co.drpj.Config;
import uk.co.drpj.gui.PianoPanel;
import uk.co.drpj.gui.Util;
import uk.co.drpj.midi.piano.Piano;
import uk.co.drpj.midi.router.ControllerHub;
import uk.co.drpj.midi.router.GMControllerList;
import uk.co.drpj.midi.voice.PatchSelector;

import com.jgoodies.looks.plastic.PlasticXPLookAndFeel;

/**
 *
 * 
 * 8  label
 * 
 * 
 * @author pjl
 */
public class MimicMain {

    static AudioAndMidiSystem system;
    static JPanel firstpanel;
    static JLabel infolabel;
    static ControllerHub hub;
    private static JFrame midiFrame;
    static Piano piano;
    static PatchSelector patchSelectorThru;
    private static Timer t;
	private static PatchSelector patchSelectorMetro;

    public static void main(String[] args) throws Exception {

    	int thruChan=0;
    	int metroChan=9;
    	
        system = new AudioAndMidiSystem();


        Synthesizer audioSynth = system.getSynth();

        Receiver synthRecv = system.getReceiver();
        hub = new ControllerHub(0, GMControllerList.cntrls);
        hub.setReceiver(synthRecv);

        patchSelectorThru = new PatchSelector(audioSynth, synthRecv,thruChan);
        patchSelectorMetro = new PatchSelector(audioSynth, synthRecv,metroChan);

        MidiDevice idev[] = system.getMidiInputs();
        Transmitter trans;


        for (int i = 0; i < idev.length; i++) {
            if (idev[i] != null) {
                idev[i].open();
                trans = idev[i].getTransmitter();
                trans.setReceiver(hub);
                System.out.println("input midi " + idev.toString() + " has been assigned ");
            }
        }

        piano = new Piano(hub);
        

        String map[][] = {{"CC108", "velocity(bow)"}, {"CC109", "pressure(bow)"},
            {"CC110", "position(bow)"}, {"CC111", "damping(bow)"}};

        for (int i = 0; i < map.length; i++) {
            String cntrlStr = Config.getProperty("control" + i);
            if (cntrlStr == null) {
                cntrlStr = map[i][0];
            }

            String effectStr = Config.getProperty("effect" + i);
            if (effectStr == null) {
                effectStr = map[i][1];
            }

            //           hub.createKnob(cntrlStr, effectStr, i);
        }
        hub.addVelsense();
        system.start();



        
        patchSelectorThru.addObserver(new Observer() {

            public void update(Observable o, Object arg) {
                Instrument inst = (Instrument) arg;
                System.out.println(" Instrument is " + inst.getName());
            }
        });

        patchSelectorThru.applyProperties(Config.getProperties());


        createGUI();

        Config.store();

        Scheduler sched=new RTScheduler();
        
        BeatAgent beatAgent=new BeatAgent(hub.getReceiver(),sched,metroChan);

        hub.addObserver(beatAgent);
        beatAgent.start();
        sched.start();
        

    }
    static JCheckBoxMenuItem mitem;
    static JCheckBoxMenuItem ditem;

   
    static void createGUI() {

        try {
            UIManager.setLookAndFeel(new PlasticXPLookAndFeel());
        } catch (Exception e) {
            e.printStackTrace();
        }


        JFrame frame = new JFrame("Midi Bow Demo");

        JMenuBar menubar = new JMenuBar();
        frame.setJMenuBar(menubar);
        JMenu menu = new JMenu("Menu");
        menubar.add(menu);
        JMenuItem item = new JMenuItem(new AbstractAction("Audio Setup") {

            public void actionPerformed(ActionEvent e) {
                system.configure();
            }
        });
        menu.add(item);


        mitem = new JCheckBoxMenuItem(new AbstractAction("Monitor Midi") {

            public void actionPerformed(ActionEvent e) {
                showMidi(mitem.isSelected());
            }
        });


        menu.add(mitem);

//        if (adminMode) {
//            item = new JMenuItem(new AbstractAction("Save Settings") {
//
//                public void actionPerformed(ActionEvent e) {
//                    //                 hub.mergeInto(Config.getProperties()); // do this here because too many to do all the time ?
//                    Config.store();
//                }
//            });
//
//
//            menu.add(item);
//        }

//        ditem = new JCheckBoxMenuItem(new AbstractAction("Admin mode (needs restart)") {
//
//            public void actionPerformed(ActionEvent e) {
//                Config.setProperty("adminMode", Boolean.toString(ditem.isSelected()));
//                //            hub.mergeInto(Config.getProperties()); // do this here because too many to do all the time ?
//                Config.store();
//            }
//        });
//
//        ditem.setSelected(adminMode);
//
//        menu.add(ditem);

        item = new JMenuItem(new AbstractAction("Exit") {

            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menu.add(item);

      


        JPanel panel=createPiano();



        frame.setContentPane(panel);

        frame.validate();
        frame.pack();
  
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        frame.setExtendedState(JFrame.MAXIMIZED_HORIZ);
        frame.setVisible(true);
  

    }
    
    static JPanel createPiano() {
        JPanel panel = new JPanel();
        //  panel.setBorder(BorderFactory.createEtchedBorder());
        panel.setBackground(Color.BLACK);

//        Dimension panelSize = new Dimension(1000, 800);
//        panel.setPreferredSize(panelSize);
//        panel.setMinimumSize(panelSize);
//        panel.setMaximumSize(panelSize);
//        panel.setSize(panelSize);


        panel.setLayout(new GridBagLayout());


        GridBagConstraints c = new GridBagConstraints();


        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridheight = 1;
        c.weighty = 0.0;
        c.weightx = 1.0;
        c.fill=GridBagConstraints.HORIZONTAL;

        Util.borderize(piano.getPanel(), "Virtual Piano");
        panel.add(piano.getPanel(), c);

        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 1;
        c.weighty = 1.0;

        c.fill = GridBagConstraints.BOTH;

       // c.fill = GridBagConstraints.VERTICAL;
        Util.borderize(patchSelectorThru.getPanel(), "Voice Selector");
        panel.add(patchSelectorThru.getPanel(), c);

        c.gridx++;
        Util.borderize(patchSelectorMetro.getPanel(), "Metro Selector");
        panel.add(patchSelectorMetro.getPanel(), c);



        c.gridx++;
        c.fill = GridBagConstraints.BOTH;
        Util.borderize(hub.getPanel(), "Controller/Effect Panel");
        panel.add(hub.getPanel(), c);
        return panel;

    }
    /**
     *
     * Allow user to play with server parameters.
     *
     */
    public static void showMidi(boolean yes) {

        hub.setDebug(yes);
        if (midiFrame != null) {
            midiFrame.setVisible(yes);
            return;
        }

        midiFrame = new JFrame(" Midi Monitor");
        // configureFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        midiFrame.setAlwaysOnTop(true);

        midiFrame.setContentPane(hub.getMonitPanel());
        midiFrame.pack();
        midiFrame.setVisible(yes);
    }
}


